//2023 12.14 00:30 星期四 雨 昨天晚 不小心滑进 吕游直播间了
import {
  getNum,
  ObjectOnlyPushSet,
  SetStaticCssTxtFunc,
  toStringTypeCheck,
} from '../../../global';
import { StackStyle } from '../styleStr2Json';
import { analysisStyleStack } from './analysisStyleStack';
/**
 * @tips 看情况 可能 会对 keyframe 进行 更迭  以及 对 信息的 整合
 * 如果有冲突 会跳出给信息 进行选择 -- 如何跳出
 */
let splitStr_ma = '/';

let StaticCss = SetStaticCssTxtFunc('mergeAnimation');

/**
 * 手动生成的 stackJson 数据
 */
let ManualStackJson = {};

/**
 * 整合后的 style Json (stackStyle)
 */
let mergeJson = {};

// /**
//  * class 对应字段
//  */
// let regClass = /[^\w]?\.(?<Classname>.*)/;

// /**
//  * ID 对应字段
//  */
// let regID = /[^\w]?#(?<IDName>.*)/;

/**
 * keyframe 对应字段
 */
let regKeyfram = /[^\w]?@keyframes (?<keyframeName>.*)/;

/**
 * 百分比 对应字段
 */
let regPer = /^(100|[1-9]?\d?)%/;

/**
 * 整合信息
 */
let mergePlat;

/**
 * 当前class 中 所存在于 keyframe 中的 数据 key
 */
let keyframeKeyArr;

/**
 * 初始化 mergePlat
 */
function initMergePlat() {
  mergePlat = {
    data: [],
    /** animation durationTime  唯一确定值 */
    durationTime: undefined,
    /** animation delayTime 唯一确定值 */
    delayTime: undefined,
    /** animation timingfunc 唯一确定值 */
    TimingFunction: undefined,
    /**所添加的 类名 (class,id) */
    areaRoom: [],
  };
  ManualStackJson = {};
  mergeJson = {};
  keyframeKeyArr = [];
}
initMergePlat();
/**
 * 分片 style 解析信息
 */
let styleLiceArr = { data: [] };
/**
 * 整合 style animation
 * -
 * 必须是 完整的 元素块 (class|id) [keyframe]
 *
 * 限制条件 -- 同步的 贝塞尔曲线 、 delaytime 、 durationtime
 *
 * 将style element 元素 进行混合杂糅 合并成 一个 class
 * 包括 keyframe 在统一时间线上 进行操作
 * 其他非动态信息 写入 class中
 * 动态信息 写入keyframes中 返回 新模式下的 json 数据 利于修改操作
 */
function mergeAnima() {
  //挨个 处理 所拥有的 style 独立 完整的 小型 style 元素块
  for (let i = 0; i < arguments.length; i++) {
    // 整理 记录 style信息
    styleLiceArr['data'].push(i);
    styleLiceArr[i] = { styleJson: StackStyle(arguments[i]) };
  }
  console.log(styleLiceArr);
  resourceMerge();

  resinkMergeJson();

  //   生成style element
  let mergeStyleStr = analysisStyleStack(ManualStackJson);
  console.log(mergeStyleStr);
  StaticCss('mergeAnima', mergeStyleStr);

  return mergeJson;
}

/**
 * 整合信息
 * -
 * 关键字 [$data,$digital]
 */
function resourceMerge() {
  let StArr = styleLiceArr;
  for (let i = 0; i < StArr['data'].length; i++) {
    mergeAnalysisStyleJson(StArr[StArr['data'][i]]['styleJson']);
  }

  console.log(mergePlat);
  //   return mergePlat;
}

/**
 * 解析 stackJson 数据 做 一个 mergePlat 数据集
 * @param {JSON} styJ 一个元素块 的 stackJson
 */
function mergeAnalysisStyleJson(styJ) {
  // console.log(styJ);
  /**
   * class id 内循环
   */
  let resq;

  /**
   * keyframe 内循环
   */
  let resq_k;

  /**
   * 当前 循环的 名称 . # keyframe
   */
  let currentName;

  /**
   * 当前时间戳
   */
  let currentTime;

  /**
   * 属性 关键字
   */
  let key;

  /**
   * 属性 值
   */
  let value;

  /** 当前值 是否第一次被添加 */
  let firstpushKey;

  //   /**
  //    * 当前 元素 延迟时间
  //    */
  //   let animadelay

  // 获取 durationTime delayTime TimingFunction 三个时间 如果不相同直接返回 融合失败

  // 类名循环
  for (let i = 0; i < styJ['$data'].length; i++) {
    //类名 -- [id,class,keyframe] 的 名称
    currentName = styJ['$data'][i];
    resq = styJ[styJ['$data'][i]];

    // mergePlat 记录 名称

    // id 样式标签
    // if (regID.test(resq)) {
    //     //绑定 mergePlat["areaRoom"] 唯一值
    //     ObjectOnlyPushSet(mergePlat,resq,undefined,"areaRoom")

    // }
    // mergePlat['areaRoom'].push(resq);

    //绑定 mergePlat["areaRoom"] 唯一值
    let resqSettlein = ObjectOnlyPushSet(
      mergePlat,
      currentName,
      undefined,
      'areaRoom'
    );
    //如果 重复插入类名 直接返回 | 记录下一个
    if (!resqSettlein) {
      //   return false;
      continue;
    }

    // 属性循环 -- $digital==true
    for (let j = 0; j < resq['$data'].length; j++) {
      // 属性标志
      if (resq['$digital']) {
        // 属性名称
        key = resq['$data'][j];
        // 属性值
        value = resq[resq['$data'][j]];

        // mergePlat 记录属性 名称 和 值
        // if (mergePlat['data'].indexOf(key) == -1) {
        //   mergePlat['data'].push(key);
        //   mergePlat[key] = {
        //     useArea: [],
        //     timestack: {},
        //     hasDynamicValue: false,
        //     value: value,
        //     dynamicValue: { timeLine: [] },
        //   };
        // }
        firstpushKey = ObjectOnlyPushSet(mergePlat, key, {
          useArea: [mergePlat['areaRoom'][mergePlat['areaRoom'].length - 1]], //取值默认为最后一个 类名域 当前域
          hasDynamicValue: false, //是否为 动态变换的 模式
          value: value, // 当前值
          dynamicValue: {
            timeLine: ['0%'],
          }, //值 的随 时间轴 变化
        });
        if (firstpushKey) {
          mergePlat[key]['dynamicValue']['0%'] = {
            /**目标索引*/ targoal: currentName,
            /** 值 */ value: value,
          };
        }

        //如果不是 第一次 记录该属性
        if (!firstpushKey) {
          let ob = mergePlat[key]['dynamicValue'];

          // mergePlat[key]["useArea"].push()
          //   添加使用域
          ObjectOnlyPushSet(
            mergePlat[key],
            mergePlat['areaRoom'][mergePlat['areaRoom'].length - 1],
            undefined,
            'useArea'
          );

          //   修改不一样的值
          if (mergePlat[key]['value'] != value) {
            mergePlat[key]['hasDynamicValue'] = true;
          }

          //   最后一次 value 值
          mergePlat[key]['value'] = value;

          // mergePlat[key]["dynamicTime"]["timeLine"].push
          //   ObjectOnlyPushSet(
          //     mergePlat[key]['dynamicTime'],
          //     dynamicTime(),
          //     value,
          //     'timeLine'
          //   );

          // 升级 targoal
          if (toStringTypeCheck(ob['0%']['targoal'], 'string')) {
            ob['0%']['targoal'] = [ob['0%']['targoal'], currentName];
          } else {
            ob['0%']['targoal'].push(currentName);
          }
          // 升级 value
          if (toStringTypeCheck(ob['0%']['value'], 'string')) {
            ob['0%']['value'] = [ob['0%']['value'], value];
          } else {
            ob['0%']['value'].push(value);
          }
        }

        //暂且 只对 animation中的 时间线进行控制添加 其他的不改变 照常处理 可能包括 transition 内容
        if (key == 'animation-name') {
          //   console.log(key);
          mergePlat[key]['hasDynamicValue'] = false;
        }
        // 对 animation-name durationTime TimingFunction  delayTime 特殊属性 进行记录
        if (key == 'animation-duration') {
          //   console.log(key);
          if (mergePlat['durationTime'] != undefined) {
            if (mergePlat['durationTime'] != value) {
              console.log(
                'sorry we got different duration Time with [' +
                  mergePlat['areaRoom'].join(',') +
                  ']'
              );
              initMergePlat();
              return false;
            }
          } else {
            mergePlat['durationTime'] = value;
          }
        }
        if (key == 'animation-timing-function') {
          //   console.log(key);
          if (mergePlat['TimingFunction'] != undefined) {
            if (mergePlat['TimingFunction'] != value) {
              console.log(
                'sorry we got different Timing Function with [' +
                  mergePlat['areaRoom'].join(',') +
                  ']'
              );
              initMergePlat();
              return false;
            }
          } else {
            mergePlat['TimingFunction'] = value;
          }
        }
        if (key == 'animation-delay') {
          //   console.log(key);
          if (mergePlat['delayTime'] != undefined) {
            if (mergePlat['delayTime'] != value) {
              console.log(
                'sorry we got different delayTime Time with [' +
                  mergePlat['areaRoom'].join(',') +
                  ']'
              );
              initMergePlat();
              return false;
            }
          } else {
            mergePlat['delayTime'] = value;
          }
        }
        // signMergePlat(key, {});

        // asignMergePlat(key, value);
      } else {
        resq_k = resq[resq['$data'][j]];

        // 记录 当前时间戳 单位 %
        if (resq['$data'][j] == 'from') {
          // 更改记录方式 0
          currentTime = '0%';
        } else if (resq['$data'][j] == 'to') {
          currentTime = '100%';
        } else {
          currentTime = resq['$data'][j];
        }

        //keyframe 模式下 需要 再进行一次 for 循环 解析
        for (let m = 0; m < resq_k['$data'].length; m++) {
          key = resq_k['$data'][m];
          value = resq_k[resq_k['$data'][m]];
          //   console.log(key + ':' + value);
          //   signMergePlat(key, '999', '666');
          //   asignMergePlat(key, value);

          // 记录 keyframe 的 属性值 和 时间戳
          firstpushKey = ObjectOnlyPushSet(mergePlat, key, {
            useArea: [mergePlat['areaRoom'][mergePlat['areaRoom'].length - 1]], //取值默认为最后一个 类名域 当前域
            hasDynamicValue: true, //是否为 动态变换的 模式
            value: value, // 当前值
            dynamicValue: {
              timeLine: [currentTime],
            }, //值 的随 时间轴 变化
          });
          mergePlat[key]['dynamicValue'][currentTime] = {
            /**目标索引*/ targoal: `${currentName}${splitStr_ma}${currentTime}`,
            /** 值 */ value: value,
          };
          if (!firstpushKey) {
            // 更迭 value
            mergePlat[key]['value'] = value;
            let ob = mergePlat[key]['dynamicValue'];

            // 根据时间戳 进行添加
            // 相同时间戳 下 升级 targoal 和 value 为数组 push 值
            if (ob['timeLine'].indexOf(currentTime) > -1) {
              // 升级 targoal
              if (toStringTypeCheck(ob[currentTime]['targoal'], 'string')) {
                ob[currentTime]['targoal'] = [
                  ob[currentTime]['targoal'],
                  `${currentName}${splitStr_ma}${currentTime}`,
                ];
              } else {
                ob[currentTime]['targoal'].push(
                  `${currentName}${splitStr_ma}${currentTime}`
                );
              }
              // 升级 value
              if (toStringTypeCheck(ob[currentTime]['value'], 'string')) {
                ob[currentTime]['value'] = [ob[currentTime]['value'], value];
              } else {
                ob[currentTime]['value'].push(value);
              }
            } else {
              ob['timeLine'].push(currentTime);
              ob[currentTime] = {
                /**目标索引*/ targoal: `${currentName}${splitStr_ma}${currentTime}`,
                /** 值 */ value: value,
              };
            }
          }
        }
      }
    }
  }
}

// /**
//  * 记录值
//  * @param {String} key 属性 关键字
//  * @param {String} value 属性 值
//  */
// function asignMergePlat(key, value) {
//   console.log(key + ':' + value);
//   if (
//     mergePlat[key]['hasDynamicValue'] == false &&
//     mergePlat[key]['value'] == value
//   ) {
//     console.log('不动');
//   }
//   if (
//     mergePlat[key]['hasDynamicValue'] == true &&
//     mergePlat[key]['value'] == value
//   ) {
//     console.log('值未变动 保持静止');
//     //   当前时间戳 - % * durationTime
//     let timedata = dynamicTime();
//     //   放置时间
//     mergePlat[key]['timeLine'].push(timedata);
//     mergePlat[key]['dynamicValue']['timeData'].push(timedata);
//     //   放置时间 改变的 value 值
//     mergePlat[key]['dynamicValue'][timedata] = value;
//   }
//   if (mergePlat[key]['value'] != value) {
//     console.log('该值 有变动 记录 动态变动信息');

//     //   拥有动态变化的值
//     mergePlat[key]['hasDynamicValue'] = true;
//     //   更新 最后一个值
//     mergePlat[key]['value'] = value;
//     //   当前时间戳 - % * durationTime
//     let timedata = dynamicTime();
//     //   放置时间
//     mergePlat[key]['timeLine'].push(timedata);
//     mergePlat[key]['dynamicValue']['timeData'].push(timedata);
//     //   放置时间 改变的 value 值
//     mergePlat[key]['dynamicValue'][timedata] = value;
//   }
// }

// function signMergePlat(key, props) {
//   if (mergePlat['data'].indexOf(key) == -1) {
//     mergePlat['data'].push(key);
//     mergePlat[key] = {
//       props,
//       timeLine: [],
//       dynamicValue: { timeData: [] },
//       value: undefined,
//       hasDynamicValue: false,
//     };
//   }
// }

/**
 * 动态 获取 该属性的 时间戳 --( 时间戳 : 当 该属性值 改变时 记录 时间戳 及其相应的 改变值)
 */
// function dynamicTime() {}

/**
 * 解析 集中处理解析的 mergeplat 转换成 stackJson 格式
 */
function resinkMergeJson() {
  let mStack = {};
  let data = '$data';
  let digital = '$digital';
  let key;
  //生成 class .a
  let cla = `.${fromCharCodeLower(0)}`;

  //生成 keyframe  @keyframes b
  let kfb = `@keyframes ${fromCharCodeLower(1)}`;
  mStack[data] = [cla, kfb];
  mStack[cla] = {};
  mStack[cla][data] = [];
  mStack[cla][digital] = true;
  mStack[kfb] = {};
  mStack[kfb][data] = [];

  for (let i = 0; i < mergePlat['data'].length; i++) {
    key = mergePlat['data'][i];
    // console.log(key, mergePlat[key]);
    /**
     * 对以下情况 进行分类:
     * 1. mergePlat[key].dynamicValue[value] 全为 同一个值 或 是一个 string -- 放置到 class 中
     */

    // 1.
    if (useAreaCheck(mergePlat[key])) {
      pushtoClass(key, mergePlat[key]);
    } else {
      keyframeKeyArr.push(key);
      pushtoKeyframe(key, mergePlat[key]);
    }
  }

  function pushtoClass(key, infos) {
    mStack[cla][data].push(key);
    mStack[cla][key] = infos['value'];
    if (key == 'animation-name') {
      mStack[cla][key] = fromCharCodeLower(1);
    }
  }

  function pushtoKeyframe(key, infos) {
    let per;
    for (let i = 0; i < infos['dynamicValue']['timeLine'].length; i++) {
      per = infos['dynamicValue']['timeLine'][i];
      ObjectOnlyPushSet(mStack[kfb][data], per);
      if (mStack[kfb][per] == undefined) {
        mStack[kfb][per] = {};
      }
      mStack[kfb][per][digital] = true;
      if (mStack[kfb][per][data] == undefined) {
        mStack[kfb][per][data] = [];
      }
      mStack[kfb][per][data].push(key);
      mStack[kfb][per][key] = chooseValue(infos, i);
    }
  }

  //   排序 keyframe 的 percent
  if (toStringTypeCheck(mStack[kfb][data], 'array')) {
    // console.log(123333);
    sortPer(mStack[kfb][data]);
  }

  ManualStackJson = mStack;
  console.log(ManualStackJson);
  athinkKeyFrame();
  return ManualStackJson;
}
// function a() {
//   resinkMergeJson();
//   //   根据两端比例进行中间值计算

//   //   生成style element
//   console.log(analysisStyleStack(ManualStackJson));
// }

/**
 * 生成 a-z (0-26) -- 97-122
 * @param {*} params
 */
function fromCharCodeLower(params) {
  if (params > -1 && params < 26) {
    return String.fromCharCode(getNum(params) + 97);
  }
}

/**
 * 解析 根据 上下文联系 解析填充
 */
function athinkKeyFrame() {
  console.log(keyframeKeyArr);
  let totalPerL = ManualStackJson[ManualStackJson['$data'][1]]['$data'].length;
  for (let i = 0; i < keyframeKeyArr.length; i++) {
    // keyframe leng < totalPerL 证明 该值 有缺失 可能需要填充
    if (
      mergePlat[keyframeKeyArr[i]]['dynamicValue']['timeLine'].length <
      totalPerL
    ) {
      contextRe(keyframeKeyArr[i]);
    }
  }
}

/**
 * 根据上下文进行填充 ManualStackJson
 * @param {String} key 缺失per 的 key
 */
function contextRe(key) {
  console.log(key, mergePlat[key], ManualStackJson);

  /**
   * 前一个值
   */
  let lastValue;
  let laper;
  /**
   * 后一个值
   */
  let nextValue;
  /**
   * 当前值
   */
  let currentValue;
  let neper;

  /**
   * 上下文填充
   * 1. 根据 相关最近的 百分比进行填充 贝塞尔函数 线性填充
   * 1.1 如果 未有上文或下文 则 按照 class中的 相关数据信息 作为 首尾默认上下文
   *
   */
  /**
   * 增加的 per 数据
   */
  let increasePer = [...ManualStackJson[ManualStackJson['$data'][1]]['$data']];
  console.log(increasePer);

  /**
   * 当前 key 值 所拥有的 per
   */
  let keyPer = [...mergePlat[key]['dynamicValue']['timeLine']];
  for (let i = 0; i < keyPer.length; i++) {
    let index = increasePer.indexOf(keyPer[i]);
    increasePer.splice(index, 1);
  }
  console.log(increasePer);

  for (let j = 0; j < increasePer.length; j++) {
    keyPer.push(increasePer[j]);
    sortPer(keyPer);
    let increaI = keyPer.indexOf(increasePer[j]);

    /**
     * 1.0.1
     * 观测 是否有前 一个 per
     */
    if (keyPer[increaI - 1] != undefined) {
      lastValue = chooseValue(mergePlat[key], keyPer[increaI - 1]);
      laper = keyPer[increaI - 1];
    } else {
      lastValue = chooseValue(mergePlat[key], '0%');
      laper = '0%';
    }
    /**
     * 1.0.2
     * 观测 是否有后 一个 per
     */
    if (keyPer[increaI + 1] != undefined) {
      nextValue = chooseValue(mergePlat[key], keyPer[increaI + 1]);
      neper = keyPer[increaI + 1];
    } else {
      nextValue = chooseValue(mergePlat[key], '0%');
      neper = '0%';
    }

    currentValue = caculateCurrentV(
      lastValue,
      nextValue,
      laper,
      neper,
      increasePer[j]
    );
    //添加新增 key
    ManualStackJson[ManualStackJson['$data'][1]][keyPer[increaI]]['$data'].push(
      key
    );
    // 添加新增 key 对应 value
    ManualStackJson[ManualStackJson['$data'][1]][keyPer[increaI]][key] =
      currentValue;

    // ObjectOnlyPushSet(ManualStackJson[ManualStackJson['$data'][1]][keyPer[increaI]],key,currentValue,"$data")
  }
}

/***tools**/
// /**
//  * 检测 数组中的值 是否相同 --只是 转换成字符串比较
//  * @param {Array} arr timeLine Value
//  * @returns {boolean}
//  */
// function alltheSameArr(arr) {
//   let a;
//   if (toStringTypeCheck(arr, 'string')) {
//     return true;
//   }
//   for (let i = 0; i < arr.length; i++) {
//     if (i == 0) {
//       a = arr[0].toString();
//     } else {
//       if (a != arr[i].toString()) {
//         return false;
//       }
//     }
//   }
//   return true;
// }

function useAreaCheck(infos) {
  for (let i = 0; i < infos['useArea'].length; i++) {
    if (regKeyfram.test(infos['useArea'][i])) {
      return false;
    }
  }
  return true;
}

function chooseValue(infos, i) {
  let val;
  if (regPer.test(i)) {
    val = infos['dynamicValue'][i]['value'];
  } else {
    val = infos['dynamicValue'][infos['dynamicValue']['timeLine'][i]]['value'];
  }

  if (toStringTypeCheck(val, 'string')) {
    return val;
  } else {
    return val[0];
  }
}

/**
 *
 * @param {Array} perArr 纯百分比 的数组
 */
function sortPer(perArr) {
  perArr.sort((a, b) => {
    // console.log(a, b);
    return getNum(a) - getNum(b);
  });
  //   console.log(perArr);
}

/**
 * 根据 前后 值得 所在位置 和 相关 timming function 计算出 当前位置的 对应的值
 * @param {String} lav last Value 前一个 值
 * @param {String} nev next value 后一个值
 * @param {String} lap last percent 前一个值的 percent 位置
 * @param {String} nep next percent 后一个值的 percent 位置
 * @param {string} cper current percent  当前 值 的 percent 位置
 */
function caculateCurrentV(lav, nev, lap, nep, cper) {
  console.log(lav, nev, lap, nep, cper);
}

export { mergeAnima, fromCharCodeLower };
